import java.net.Socket;
import java.util.*;

public class StudentSystem {
    private Socket socket;
    private Monitor monitor;
    private Student student;
    private final Scanner SC = ClientScanner.sc;
    private List<ChoiceQuestion> choiceQuestions;
    private List<TrueOrFalseQuestion> trueOrFalseQuestions;

    public StudentSystem(Socket socket, Monitor monitor, Student student, List<?>[] allQuestions) {
        this.socket = socket;
        this.monitor = monitor;
        this.student = student;
        choiceQuestions = MyTool.castList(allQuestions[0], ChoiceQuestion.class);
        trueOrFalseQuestions = MyTool.castList(allQuestions[1], TrueOrFalseQuestion.class);
    }

    public void launch() {
        String input;
        do {
            Displayer.printStudentFrame(student.getName());
            input = inputJudge("[012]");
            switch (input) {
                case "0":return;
                case "1": userModule();break;
                case "2":examModule();break;
            }
        } while (!input.matches("0"));
    }

    private String inputJudge( String regex) {
        return ClientScanner.inputJudge(regex);
    }

    private void userModule() {
        String input;
        do {
            Displayer.printUserModuleFrame();
            input = inputJudge("[012]");
            switch (input) {
                /*修改昵称*/
                case "1":{
                    System.out.println("你现在的昵称是:" + student.getName());
                    System.out.println("修改昵称为:");
                    String tName = inputJudge("[\\S][\\S ]*[\\S]");
                    new ClientSendThread(socket, new Message("changeName",
                            new Command(student.getUserName()+" "+tName))).start();
                    System.out.println("昵称修改成功");
                    break;
                }
                /*修改密码*/
                case "2":{
                    System.out.println("请输入当前密码:");
                    String tCurrentPassword = SC.nextLine();
                    while (!tCurrentPassword.equals(student.getPassword())&&!tCurrentPassword.equals("0")) {
                        System.out.println("密码错误, 重新输入或输入'0'返回");
                        tCurrentPassword = SC.nextLine();
                    }
                    if (tCurrentPassword.equals(student.getPassword())) {
                        System.out.println("请输入新密码:");
                        String newPassword = inputJudge("[\\S]+");
                        System.out.println("请再次输入新密码:");
                        String tPasswordAgain = inputJudge("[\\S]+");
                        if (newPassword.equals(tPasswordAgain)) {
                            new ClientSendThread(socket, new Message("changePassword",
                                    new Command(student.getUserName()+" "+newPassword) )).start();
                            System.out.println("密码修改成功");
                        }
                        else {
                            System.out.println("两次输入的密码不一致");
                        }
                    }
                    break;
                }
                case "0":{
                    break;
                }
            }
        } while (!input.matches("0"));
    }
    private void examModule() {
        String input;
        do {
            Displayer.printExamModuleFrame();
            input = inputJudge("[0123]");
            switch (input) {
                case "1":{
                    System.out.println("请输入试卷题目数:");
                    String tInput = inputJudge("[12345]");
                    startExam(buildExamPaper(Integer.parseInt(tInput)));
                    new ClientSendThread(socket, new Message("refreshExamRecord", student)).start();
                    break;
                }
                case "2":{student.showExamRecord();}
                case "3":{}
                case "0":{}
            }
        } while (!input.matches("0"));
    }

    private void startExam(ExamPaper examPaper) {
        int answeredCount = 0;
        int rightCount = 0;
        int cQuestionCount = examPaper.cQuestions.size();
        int tofQuestionCount = examPaper.tofQuestions.size();
        int questionCount = cQuestionCount+tofQuestionCount;
        String input;
        double getScore = 0;
        double fullScore = cQuestionCount*ChoiceQuestion.SCORE_VALUE+
                    tofQuestionCount*TrueOrFalseQuestion.SCORE_VALUE;
        for (int i = 0; i < questionCount; i++) {
            for (ChoiceQuestion item : examPaper.cQuestions) {
                Displayer.printOneChoiceQuestion(item,i+1);
                input = inputJudge("[ABCD]|[abcd]");
                answeredCount++;
                if (input.equalsIgnoreCase(item.getAnswer())) {
                    System.out.println("回答正确");
                    rightCount++;
                    getScore += ChoiceQuestion.SCORE_VALUE;
                }else {
                    System.out.println("回答错误");
                }
                i++;
            }
            for (TrueOrFalseQuestion item : examPaper.tofQuestions) {
                Displayer.printOneTrueOrFalseQuestion(item, i+1);
                input = inputJudge("true|false");
                answeredCount++;
                if (input.equalsIgnoreCase(item.getAnswer())) {
                    System.out.println("回答正确");
                    rightCount++;
                    getScore += TrueOrFalseQuestion.SCORE_VALUE;
                }else {
                    System.out.println("回答错误");
                }

                i++;
            }
        }
        double score = getScore/fullScore*100;
        ExamRecord record = student.examRecord;
        record.accuracy = (record.accuracy*record.answeredQuestionNumber+rightCount)/
                        (record.answeredQuestionNumber+answeredCount);
        record.answeredQuestionNumber += answeredCount;
        record.averageScore = (record.averageScore*record.examTimes+score)/(record.examTimes+1);
        record.examTimes++;
        System.out.println("考试结束。");
        System.out.println("一共有"+questionCount+"道题, 你答对了"+rightCount+
                "道, 答错了"+(questionCount-rightCount)+"道\n本次考试得分(百分制):"+MyTool.myFormat(score));
        System.out.println("输入'0'返回");
        inputJudge("0");
    }

    private ExamPaper buildExamPaper(int questionCount) {
        ExamPaper examPaper = new ExamPaper(questionCount);
        TrueOrFalseQuestion[] tofQ = new TrueOrFalseQuestion[questionCount/2];
        ChoiceQuestion[] cQ = new ChoiceQuestion[questionCount-tofQ.length];
        List<ChoiceQuestion> cList = new ArrayList<>(choiceQuestions);
        List<TrueOrFalseQuestion> tofList = new ArrayList<>(trueOrFalseQuestions);
        Collections.shuffle(cList);
        Collections.shuffle(tofList);
        for (int i = 0; i < cQ.length; i++) {
            cQ[i] = cList.get(i);
        }
        for (int i = 0; i < tofQ.length; i++) {
            tofQ[i] = tofList.get(i);
        }
        examPaper.cQuestions.addAll(Arrays.asList(cQ));
        examPaper.tofQuestions.addAll(Arrays.asList(tofQ));
        return examPaper;
    }
}
